﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

using Txt2Shp4Sharp.lib;
using SharpMap.Layers;
using SharpMap.Data.Providers;
using SharpMap;
using SharpMap.Data;
using GeoAPI.Geometries;

namespace Txt2Shp4Sharp.FormView
{
    public partial class FormShp2Txt : Form
    {
        private IGlobalApplication m_pluginApplication=null;
        private string m_batchOutputpath = "";
        private Dictionary<string, int> m_attrsFieldIndexDic=null;
        private string m_dataProduceOrg = "重庆市规划和自然资源调查监测院";
        private string m_degreeNum = "36";

        public FormShp2Txt()
        {
            InitializeComponent();
        }
        public FormShp2Txt(IGlobalApplication pluginApplication)
        {
            InitializeComponent();

            this.m_pluginApplication = pluginApplication;
        }

        private void FormShp2Txt_Load(object sender, EventArgs e)
        {
            
        }

        #region  私有函数
        
        private int shp2txt_bat(string layerName)
        {
            String dzjghFieldName = "DZJGH";
            String xmmcFieldName = "XMMC";
            String tdytFieldName = "TDYT";
            String txjsmjFieldName = "TXJSMJ";
            m_attrsFieldIndexDic = new Dictionary<string, int>();

            int indexOfDzjgh = -1;

            VectorLayer pfeaLayer = this.m_pluginApplication.getLayerByName(layerName);
            SharpMap.Data.Providers.ShapeFile shapeFile = (ShapeFile)pfeaLayer.DataSource;
            if (!shapeFile.IsOpen) {
                shapeFile.Open();
            }
            //查找电子监管号
            int featureCount = shapeFile.GetFeatureCount();
            if (featureCount > 0) {
                FeatureDataRow feature = shapeFile.GetFeature(0);
                int i = 0;
                foreach (var key in feature.ItemArray)
                {
                    if (key == dzjghFieldName)
                    {
                        indexOfDzjgh = i;
                        m_attrsFieldIndexDic.Add(dzjghFieldName, i);
                    }
                    else if (key == xmmcFieldName)
                    {
                        m_attrsFieldIndexDic.Add(xmmcFieldName, i);
                    }
                    else if (key == tdytFieldName)
                    {
                        m_attrsFieldIndexDic.Add(tdytFieldName, i);
                    }
                    else if (key == txjsmjFieldName)
                    {
                        m_attrsFieldIndexDic.Add(txjsmjFieldName, i);
                    }

                    i++;
                }
                
            }

            //获取所有的电子监管号列表
            List<string> dzjghList = new List<string>();
            for(int i = 0; i<featureCount; i++) {
                FeatureDataRow feature = shapeFile.GetFeature((uint)i);
                if (feature == null)
                {
                    foreach (var key in feature.ItemArray)
                    {
                        if (key == dzjghFieldName)
                        {
                            string dzjgh = feature[dzjghFieldName].ToString().Trim();
                            if (!string.IsNullOrEmpty(dzjgh) && !dzjghList.Contains(dzjgh))
                            {
                                dzjghList.Add(dzjgh);
                            }
                        }
                    }
                }
            }

           
            this.listView_pzwhList.Items.Clear();

            int dzjghCount = dzjghList.Count;
            for (int i = 0; i < dzjghCount; i++)
            {
                string dzjgh = dzjghList[i];
                string filename = dzjgh + ".txt";
                string msg = string.Format("正在处理第{0}个记录,{1}", i, dzjgh);
                ListViewItem lvItem = new ListViewItem(new string[] { (i +1)+ "", dzjgh });
                this.listView_pzwhList.Items.Add(lvItem);

                String sql=string.Format("{0}='{1}'", dzjghFieldName, dzjgh);

                // 创建一个用于存储匹配的要素的列表
                var matchedFeatures = new List<FeatureDataRow>();

                // 遍历所有要素并根据属性值过滤
                for (int j = 0; j < featureCount; j++)
                {
                    FeatureDataRow  feature = shapeFile.GetFeature((uint)j) as FeatureDataRow;
                    if ( feature != null && feature[dzjghFieldName].ToString() == dzjgh ){
                        // 添加到匹配的要素列表
                        matchedFeatures.Add(feature);
                    }
                }

                if (matchedFeatures != null && matchedFeatures.Count>0)
                {
                    //shp2txt(pFeaCursor2, filename);
                }
            }

            shapeFile.Close();

            return dzjghCount;
        }
       
        private string shp2txt(List<FeatureDataRow> pFeaCursor, string fileName)
        {
            string filePath = m_batchOutputpath + "\\" + fileName;
            System.IO.FileStream fs = new System.IO.FileStream(filePath, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);

            String dateNowStr =  DateTime.Now.ToString("yyyy-MM-dd");

            sw.WriteLine("[属性描述]");
            sw.WriteLine("格式版本号=" + "1.0版本");
            sw.WriteLine("数据产生单位=" + m_dataProduceOrg);
            sw.WriteLine("数据产生日期=" + dateNowStr);
            sw.WriteLine("坐标系=" + "2000国家大地坐标系");
            sw.WriteLine("几度分带=" + 3);
            sw.WriteLine("投影类型=" + "高斯克吕格");
            sw.WriteLine("计量单位=" + "米");
            sw.WriteLine("带号=" +m_degreeNum);
            sw.WriteLine("精度=" + "0.001");
            sw.WriteLine("转换参数=" + "0,0,0,0,0,0,1");
            sw.Flush();

            int blockIndex = 1;

            int count = pFeaCursor.Count;
            for (int i= 0; i < count; int++){
                FeatureDataRow fea=pFeaCursor[i];

                double dkmj = 0.0;
                string dkbh = "地块" + blockIndex;
                string dkmc = fea[(m_attrsFieldIndexDic["XMMC"]).ToString();
                string jltxsx = "";
                string tfh = "";
                string dkyt = pFea.get_Value(m_attrsFieldIndexDic["TDYT"]).ToString();
                //图形计算面积
                double.TryParse(pFea.get_Value(m_attrsFieldIndexDic["TXJSMJ"]).ToString(), out dkmj);
                
                IPolygon4 polygon = pFea.Shape as IPolygon4;
                //地块面积
                //IArea pArea = polygon as IArea;
                //double area = pArea.Area;
                //dkmj = area;

                IGeometryBag pExteriorRingGeoBag = polygon.ExteriorRingBag;  //获取多边形的所有外环
                IGeometryCollection pExteriorRingGeoCollection = pExteriorRingGeoBag as IGeometryCollection;
                for (int i = 0; i < pExteriorRingGeoCollection.GeometryCount; i++)
                {
                    //外环-地块                    
                    int exteriorRingIndex = 1;
                    IGeometry exteriorRingGeo = pExteriorRingGeoCollection.get_Geometry(i);
                    IPointCollection exteriorRingPointCollection = exteriorRingGeo as IPointCollection;

                    int jzdCount = exteriorRingPointCollection.PointCount; //界址点个数

                    //非常重要，获取exteriorRingGeo外环包含的所有内环，即岛宗
                    IGeometryBag interiorRingGeoBag = polygon.get_InteriorRingBag(exteriorRingGeo as IRing); 
                    IGeometryCollection interiorRingGeoCollection = interiorRingGeoBag as IGeometryCollection;
                    for (int ii = 0; ii < interiorRingGeoCollection.GeometryCount; ii++)
                    {
                        IGeometry innerRingGeo = interiorRingGeoCollection.get_Geometry(ii);
                        IPointCollection innerPointCol = innerRingGeo as IPointCollection;
                        //读取当前block下所有内环（岛）的节点数
                        int innerPtCount = innerPointCol.PointCount;

                        jzdCount += innerPtCount;
                    }

                    //坐标序列台头
                    //界址点数,地块面积,地块编号,地块名称,记录图形属性(点、线、面),图幅号,地块用途,地类编码,@                  
                    string blockHeader = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}",
                        jzdCount, dkmj, dkbh, dkmc, jltxsx, tfh, dkyt, "地类编码", "@");

                    sw.WriteLine("[地块坐标]");
                    sw.WriteLine(blockHeader);
                    sw.Flush();

                    //界址点顺序号
                    int pointIndex = 0;
                    //外环
                    for (int j = 0; j < exteriorRingPointCollection.PointCount; j++)
                    {
                        pointIndex++;
                        IPoint pt = exteriorRingPointCollection.get_Point(j);

                        //J1, 1, x, y
                        string line = string.Format("{0},{1},{2},{3}", "J" + pointIndex, exteriorRingIndex, pt.X, pt.Y);
                        sw.WriteLine(line);
                    }

                    //内环-岛宗
                    for (int m = 0; m < interiorRingGeoCollection.GeometryCount; m++)
                    {                       
                        IGeometry interiorRingGeo = interiorRingGeoCollection.get_Geometry(m);
                        IPointCollection interiorRingPointCollection = interiorRingGeo as IPointCollection;
                        for (int n = 0; n < interiorRingPointCollection.PointCount; n++)
                        {
                            pointIndex++;
                            IPoint pt = interiorRingPointCollection.get_Point(n);
                            
                            string line = string.Format("{0},{1},{2},{3}", "J" + pointIndex, exteriorRingIndex + m + 1, pt.X, pt.Y);
                            sw.WriteLine(line);
                        }
                    }
                    sw.Flush();
                }
                sw.Flush();

                pFea = pFeaCursor.NextFeature();
                blockIndex++;
            }

            sw.Flush();
            sw.Close();

            return fileName;
        }
        

        #endregion

        private void btnShp2Txt_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Button btn = (System.Windows.Forms.Button)sender;
            String btnName =btn.Name;
            switch (btnName)
            {
                case "btnShp2Txt_OutputSet":
                    //输入路径（文件夹）
                    m_batchOutputpath = "";
                    FolderBrowserDialog folderDialog = new FolderBrowserDialog();
                    folderDialog.Description = "请选择Txt文件输出路径";
                    if (folderDialog.ShowDialog() == DialogResult.OK)
                    {
                        m_batchOutputpath = folderDialog.SelectedPath;
                    }
                    if (m_batchOutputpath == String.Empty)
                    {
                        return;
                    }

                    this.textBox_outputPath.Text = m_batchOutputpath;

                    //待处理的Txt文件列表
                    this.listView_pzwhList.Items.Clear();
                    //ListTxtFile(m_batchinputpath);

                    //this.numoftxtfiles = this.listView1.Items.Count;
                    break;

                case "btnShp2Txt_loadShpFeature":

                    break;
                case "btnShp2Txt_BeginConvert":
                    string layername = this.comboBox_targetLayer.Text;
                    if (!string.IsNullOrEmpty(m_batchOutputpath) && !string.IsNullOrEmpty(layername))
                    {
                        m_dataProduceOrg = this.textBox_dataProduceOrg.Text;
                        m_degreeNum = this.textBox_degreeNum.Text;

                        String msgStr1 = String.Format("Shp转Txt正在处理中---> 图层名：{0}", layername);
                        this.label_Shp2TxtState.Text = msgStr1;

                        //int successNum = shp2txt_bat(layername);//核心代码-shp2txt
                        int successNum = -1;

                        String msgStr2 = String.Format("Shp转Txt处理完成---> 图层名：{0},一共转换了 {1} 个记录", layername, successNum);
                        this.label_Shp2TxtState.Text = msgStr2;
                        MessageBox.Show(msgStr2, "转换完成");

                        this.Close();
                    }
                    break;
            }
            
        }
        

        private void comboBox_targetLayer_SelectedIndexChanged(object sender, EventArgs e)
        {
            string layerName = this.comboBox_targetLayer.Text;
            if (layerName != null && layerName != "")
            {
                VectorLayer feaLayer = this.m_pluginApplication.getLayerByName(layerName);
                //this.m_pluginApplication.resetFieldList(feaLayer, comboBox_fieldSelect);
            }
        }

    }
}
